home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume7 / tm < prev    next >
Encoding:
Text File  |  1989-07-02  |  8.1 KB  |  293 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Subject: v07i054: simple vt100 emulator for Apollos
  4. Reply-To: s8730679@spectrum.eecs.unsw.oz.au ( The Inquisitor )
  5.  
  6. Posting-number: Volume 7, Issue 54
  7. Submitted-by: s8730679@spectrum.eecs.unsw.oz.au ( The Inquisitor )
  8. Archive-name: tm
  9.  
  10.     I wrote this program after becoming frustrated at the
  11. regular failure on the part of the apollo vt100 emulator to
  12. come up. It is a simple terminal emulator which is sufficient
  13. to run vn. Hack crashes under it and there are bugs, but it is
  14. the shell of a decent emulator.
  15.  
  16.         Troy Rollo
  17.     avenger@runx.ips.oz.au
  18.     s8730679@spectrum.eecs.unsw.oz.au
  19.     8730679@elec70a.eecs.unsw.oz.au
  20.     troy_rollo@712.502@fidogate.fido.oz.au
  21.  
  22. #! /bin/sh
  23. # This is a shell archive.  Remove anything before this line, then
  24. # unpack it by saving it in a file and typing "sh file".  (Files
  25. # unpacked will be owned by you and have default permissions.)
  26. #
  27. # This archive contains:
  28. # README Makefile termcap tm.c
  29.  
  30. echo x - README
  31. cat > "README" << '//E*O*F README//'
  32.          Thisterm terminal emulator
  33.  
  34.     By Troy Rollo 1989
  35.  
  36.     The thisterm terminal emulator is a minimum terminal
  37.     emulator for the apollo domains. This version has only
  38.     two control sequences:
  39.         Ctrl-L (ascii 0xc) clears the screen (pad)
  40.         An escape character followed by x+' ', y+' ' moves
  41.     to the given location in the pad.
  42.  
  43.     Additional control sequences can be created by modifying
  44.     the xfread routine. The ones already installed can, of course
  45.     be modified.
  46.  
  47.     Thisterm uses the pseudo tty device entries /dev/ptypb and
  48.     /dev/ttypb. An improved version would start at [pt]typ0 and work
  49.     up towards [pt]typf, allowing more than one thisterm
  50.     terminal emulator to run at once. It might also remove borders,
  51.     and use pad_$set_full_window and the current scale factor to
  52.     set the size of the window to match the size of the pseudo
  53.     screen.
  54.  
  55.     To use this, first run thisterm, then set the environment variables:
  56.  
  57.     MORE=-c
  58.     TERM=this
  59.     TERMCAP=your_termcap_path
  60.  
  61.     avenger@runx.ips.oz.au
  62.     s8730679@spectrum.eecs.unsw.oz.au (sometimes)
  63.     8730679@elec70a.eecs.unsw.oz.au (sometimes)
  64.     troy_rollo@712.502@fidogate.fido.oz.au (can't reply)
  65. //E*O*F README//
  66.  
  67. echo x - Makefile
  68. cat > "Makefile" << '//E*O*F Makefile//'
  69. # Makefile for thisterm
  70. # Very easy:
  71.  
  72. thisterm: tm.c
  73.     cc -o thisterm tm.c
  74. //E*O*F Makefile//
  75.  
  76. echo x - termcap
  77. cat > "termcap" << '//E*O*F termcap//'
  78. #
  79. # Termcap file for my news reading emulator
  80. #
  81. # run tm, then set:
  82. #
  83. #    MORE=-c
  84. #    TERM=this
  85. #    TERMCAP=$HOME/termcap
  86. #
  87. th|this|this emulator:\
  88.     :cm=\E%r%+ %+ :cl=\14:li#25:co#80:bs:
  89. //E*O*F termcap//
  90.  
  91. echo x - tm.c
  92. cat > "tm.c" << '//E*O*F tm.c//'
  93. /* thisterm terminal emulator
  94.     By Troy Rollo 1989
  95.  
  96.     The thisterm terminal emulator is a minimum terminal
  97.     emulator for the apollo domains. This version has only
  98.     two control sequences:
  99.         Ctrl-L (ascii 0xc) clears the screen (pad)
  100.         An escape character followed by x+' ', y+' ' moves
  101.     to the given location in the pad.
  102.  
  103.     Additional control sequences can be created by modifying
  104.     the xfread routine. The ones already installed can, of course
  105.     be modified.
  106.  
  107.     Thisterm uses the pseudo tty device entries /dev/ptypb and
  108.     /dev/ttypb. An improved version would start at [pt]typ0 and work
  109.     up towards [pt]typf, allowing more than one thisterm
  110.     terminal emulator to run at once. It might also remove borders,
  111.     and use pad_$set_full_window and the current scale factor to
  112.     set the size of the window to match the size of the pseudo
  113.     screen.
  114.  
  115.     avenger@runx.ips.oz.au
  116.     s8730679@spectrum.eecs.unsw.oz.au (sometimes)
  117.     8730679@elec70a.eecs.unsw.oz.au (sometimes)
  118.     troy_rollo@712.502@fidogate.fido.oz.au (can't reply)
  119. */
  120.  
  121. #include <netdb.h>
  122. #include <stdio.h>
  123. #include <signal.h> 
  124. #include <fcntl.h>
  125. #include <apollo/base.h>
  126. #include <apollo/pad.h>
  127. #include <apollo/error.h>
  128.  
  129. #define COLUMNS 80
  130. #define ROWS 25
  131.  
  132. /* I think fd2p is a relic from a previous life. This program evolved
  133.     from an rexec patron */
  134. int fd2p = 1;
  135. status_$t status;
  136. stream_$sk_t sk = {
  137.         0l,
  138.         0l,
  139.         0l
  140.     };
  141.  
  142. /* Hmm... interesting... I don't actually use argc or argv */
  143. main(int argc, char **argv)
  144. {
  145.         char c[256];    
  146.         int cc;
  147.         int n;
  148.         int pn, pid;
  149.     int rem, proc;
  150.         
  151.  
  152.     /* put the pad in raw mode. This is a requirement for any terminal
  153.        emulator */
  154.     pad_$raw(1, &status);
  155.     /* Now open the master side of the pseudo tty */
  156.     rem=open("/dev/ptypb", O_RDWR);
  157.     /* And the slave side */
  158.     proc=open("/dev/ttypb", O_RDWR);
  159.         if (rem==-1 || proc==-1)
  160.         /* Complain if unable to open either - probably should
  161.            try to find another one */
  162.         exit(1);
  163.     if((pid=fork())==-1) {
  164.         fprintf(stderr, "%s: can't fork\n", argv[0]);
  165.         exit(1);
  166.     }
  167.     if (pid==0) {
  168.         /* This process lives on the slave side of the pseudo tty
  169.            Make the pseudo tty stdin, stdout and stderr */
  170.         close(0);
  171.         close(1);
  172.         close(2);
  173.         dup(proc);
  174.         dup(proc);
  175.         dup(proc);
  176.         close(proc);
  177.         close(rem);
  178.         /* I use ksh - you might prefer another shell */
  179.         execl("/bin/ksh", "ksh", "-i", 0);
  180.     }
  181.     close(proc);
  182.     /* Close the slave side so that when the last slave side process dies
  183.        or closes its last file descriptor we hear about it on the master side */
  184.         if ((pn=fork())==-1) {
  185.         fprintf(stderr, "%s: Can't fork\n", argv[0]);
  186.         kill(pid,9);
  187.         exit(1);
  188.         }
  189.     /* Create a frame to allow the cursor to roam around the pseudo screen */
  190.     pad_$create_frame(1, COLUMNS, ROWS, &status);
  191.     /* The parent reads on the master side (output of the slace side) until
  192.        there are no more processes writing on the pseudo tty. At this point
  193.        it enters a suicide pact - killing the child with a machine gun (signal
  194.        9) and dieing itself.
  195.        Intil it dies, the slave side transfers all stdin to the pseudo tty    */
  196.         if (pn!=0) {
  197.         while (xfread(rem) !=-1);
  198.         pad_$cooked(1, &status);
  199.         pad_$delete_frame(1, &status);
  200.         kill(pn, 9);
  201.         exit(0);
  202.         }
  203.         else {
  204.             while ((n=read(0, c, 255)) != 0)
  205.             write(rem, c, n);
  206.         }
  207. }
  208.  
  209.  
  210. /* xfread reads from the pseudo tty, and decides what to do about the output.
  211.    It's fairly straight forward - checks for any specified control character.
  212.    There is a bug in the newline sequence - if the user presses the page up or
  213.    shift-uparrow keys, you can't get back on the current frame.... perhaps these
  214.    keys should be redefined within the region of the pad.
  215.     Some enhancements might be:
  216.    A partial screen clearing option.
  217.    Scroll forward and back on demand.
  218.    Changing font (perhaps loading an inverse font and using it for highlight.
  219.     the following fonts could also prove useful as built-ins:
  220.       italics
  221.       bold
  222.       times_roman
  223.     as well as a pure graphics font (say, a 7x1 font with each character
  224.     representing a sequence of pixels in a vertical line)
  225.    This routine doesn't return until there are no more slaves using the pseudo
  226.    tty
  227. */
  228. int xfread(f)
  229. int f;
  230. {
  231.     char b;
  232.     short x, y;
  233.     long line, eof;
  234.     short xo, yo;
  235.  
  236.     while (kread(f,&b)!=-1)
  237.         if (b=='\033') {
  238.             kread(f,&b);
  239.             x=(short) (b-' '+1);
  240.             kread(f,&b);
  241.             y=(short) (b-' '+1);
  242.             pad_$inq_view(1, 1, &line, &eof, &xo, &yo, &status);
  243.             pad_$move(1,pad_$absolute,x,y+yo-1,&status);
  244.             write(1,"\0",2);
  245.         }
  246.         else if (b=='\014') {
  247.             pad_$clear_frame(1, sk, &status);
  248.             write(1,"\0",2);
  249.         }
  250.         else {
  251.             write(1,&b,1);
  252.             if (b=='\n') {
  253.                 pad_$inq_view(1, 1, &line, &eof, &xo, &yo, &status);
  254.                 pad_$inq_position(1, &x, &y, &status);
  255.                 if (y-yo+1==25) {
  256.                     pad_$set_view(1, 1, line, 1, yo+2, &status);
  257.                     pad_$create_frame(1, COLUMNS, ROWS, &status);
  258.                 }
  259.             }
  260.         }
  261.     return (-1);
  262. }
  263.  
  264. /* A buffered read - returns 1 on success, -1 on failure (just to be difficult for
  265.    anybody using it as the argument to if! And also for compatibility with the
  266.    values returned by Domain/IX
  267.    returns one character at a time, buffering them in a static 2048 byte buffer.
  268.    interesting things would happen if two different files were used as arguments
  269.    int different parts of the program, but it's probably not worth fixing */
  270. int kread(file, buffer)
  271. int file;
  272. char *buffer;
  273. {
  274.     static char BIGBUF[2048];
  275.     static int bbcnt = 0;
  276.     static int bbptr = 0;
  277.  
  278.     if (bbptr>=bbcnt) {
  279.         bbcnt=read(file, BIGBUF, 2048);
  280.         if (bbcnt==-1)
  281.             return(-1);
  282.         bbptr=0;
  283.     }
  284.     *buffer=BIGBUF[bbptr];
  285.     ++bbptr;
  286.     return(1);
  287. }
  288. //E*O*F tm.c//
  289.  
  290. exit 0
  291.  
  292.  
  293.